import { BufferGeometry3D, Curve, Vector3 } from 'feng3d-three';
import { ParametricGeometries } from '../thirdparty/three/imports';

export class ParametricGeometries3D
{
    static plane(width: number, height: number)
    {
        const result = ParametricGeometries.plane(width, height);

        return result;
    }

    static klein(v: number, u: number, target: Vector3)
    {
        const result = ParametricGeometries.klein(v, u, target);

        return result;
    }

    static mobius(u: number, t: number, target: Vector3)
    {
        const result = ParametricGeometries.mobius(u, t, target);

        return result;
    }

    static get TorusKnotGeometry3D()
    {
        return TorusKnotGeometry3D;
    }

    static get SphereGeometry3D()
    {
        return SphereGeometry3D;
    }

    static get TubeGeometry3D()
    {
        return TubeGeometry3D;
    }
}

class TorusKnotGeometry3D extends BufferGeometry3D
{
    get _geometry()
    {
        if (!this.__geometry)
        {
            this.__geometry = new ParametricGeometries.TorusKnotGeometry(this.radius, this.tube, this.segmentsT, this.segmentsR, this.p, this.q);
        }

        return this.__geometry;
    }
    declare protected __geometry: ParametricGeometries.TorusKnotGeometry;

    radius?: number;
    tube?: number;
    segmentsT?: number;
    segmentsR?: number;
    p?: number;
    q?: number;
}

class SphereGeometry3D extends BufferGeometry3D
{
    get _geometry()
    {
        if (!this.__geometry)
        {
            this.__geometry = new ParametricGeometries.SphereGeometry(this.size, this.u, this.v);
        }

        return this.__geometry;
    }
    declare protected __geometry: ParametricGeometries.SphereGeometry;

    size: number;
    u: number;
    v: number;
}

class TubeGeometry3D extends BufferGeometry3D
{
    get _geometry()
    {
        if (!this.__geometry)
        {
            this.__geometry = new ParametricGeometries.TubeGeometry(this.path, this.segments, this.radius, this.segmentsRadius, this.closed);
        }

        return this.__geometry;
    }
    declare protected __geometry: ParametricGeometries.TubeGeometry;

    path: Curve<Vector3>;
    segments?: number;
    radius?: number;
    segmentsRadius?: number;
    closed?: boolean;
}
